package com.example.demo810.api;

import com.example.demo810.biz.SysUserService;
import com.example.demo810.cfg.IgnoreSecurity;
import com.example.demo810.po.JwtProperties;
import com.example.demo810.po.SysInfo;
import com.example.demo810.po.SysUser;
import com.example.demo810.po.SysUserRole;
import com.example.demo810.repo.UserRoleRepo;
import com.example.demo810.util.RedisUtils;
import com.example.demo810.vo.AjaxResponse;
import com.example.demo810.vo.UserRegisterReq;
import com.example.demo810.vo.UserRegisterResp;
import com.google.code.kaptcha.impl.DefaultKaptcha;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import sun.misc.BASE64Encoder;

import javax.imageio.ImageIO;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
import java.util.concurrent.TimeUnit;


/**
 * @author lzh
 * @date 2020/8/10 - 10:43
 */
@RestController
@Api(tags = "登录相关")
public class LoginController {
    private final DefaultKaptcha defaultKaptcha;
    private final SysUserService sysUserService;
    private final UserRoleRepo userRoleRepo;
    private final BCryptPasswordEncoder bCryptPasswordEncoder;
    private final RedisUtils redisUtils;

    public LoginController(DefaultKaptcha defaultKaptcha, RedisUtils redisUtils, SysUserService sysUserService, UserRoleRepo userRoleRepo, BCryptPasswordEncoder bCryptPasswordEncoder) {
        this.defaultKaptcha = defaultKaptcha;
        this.redisUtils = redisUtils;
        this.sysUserService = sysUserService;
        this.userRoleRepo = userRoleRepo;
        this.bCryptPasswordEncoder = bCryptPasswordEncoder;
    }


    @ApiOperation(value = "生成base64验证码")
    @GetMapping(value = "/captcha")
    @IgnoreSecurity(name = "忽略token校验")
    public AjaxResponse<Map<String,Object>> defaultKaptcha(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse)
            throws Exception {
        UUID uuid = UUID.randomUUID();
        String verifyKey = "captcha_" + uuid;

        ByteArrayOutputStream jpegOutputStream = new ByteArrayOutputStream();
        try {
            // 生产验证码字符串并保存到 redis 中
            String createText = defaultKaptcha.createText();
            System.out.println("验证码: " + createText+"---验证码有效期3分钟---");
            redisUtils.setCacheDiy(verifyKey, createText, 3, TimeUnit.MINUTES);


            // 使用生成的验证码字符串返回一个BufferedImage对象并转为byte写入到byte数组中
            BufferedImage challenge = defaultKaptcha.createImage(createText);
            ImageIO.write(challenge, "jpg", jpegOutputStream);
        } catch (IllegalArgumentException e) {
            httpServletResponse.sendError(HttpServletResponse.SC_NOT_FOUND);
            return AjaxResponse.error("生成验证码失败");
        }

        // 对字节数组Base64编码
        BASE64Encoder base64Encoder = new BASE64Encoder();
        String base64 = base64Encoder.encode(jpegOutputStream.toByteArray());
        String captchaBase64 = "data:image/jpeg;base64," + base64.replaceAll("\r\n", "");
        Map<String,Object> res = new HashMap();
        res.put("pic64",captchaBase64);
        res.put("uuid",uuid);
        return AjaxResponse.successMsgData("生成base64验证码成功!", res);


    }




//-----------------------------------------------------


    @GetMapping("/")
    @ApiOperation("json版系统欢迎页")
    @IgnoreSecurity(name = "忽略token校验测试接口")
    public AjaxResponse<SysInfo> testSys() {
        return AjaxResponse.successMsgData("欢迎访问!", SysInfo.builder()
                .appName("权限管理系统").appVersion("V1.0")
                .build());
    }


    @GetMapping("/ping")
    @ApiOperation("忽略token校验")
    @IgnoreSecurity(name = "忽略token校验测试接口")
    public AjaxResponse<Void> test1() {
        return AjaxResponse.successMsg("忽略token校验,访问成功!");
    }


    @GetMapping("/testToken")
    @ApiOperation("带TOKEN访问测试接口")
    public AjaxResponse<Void> test2(@RequestHeader String accessToken) {
        return AjaxResponse.successMsg("带TOKEN访问成功!");
    }


    @PostMapping("/register")
    @ApiOperation("用户注册")
    @IgnoreSecurity(name = "忽略token校验")
    @Transactional(rollbackFor = Exception.class)
    public AjaxResponse<UserRegisterResp> registerUser(@RequestBody @Validated UserRegisterReq registerReq) {
        SysUser nUser = SysUser.builder()
                .username(registerReq.getUsername())
                .password(bCryptPasswordEncoder.encode(registerReq.getPassword()))
                .build();

        sysUserService.insert(nUser);

        userRoleRepo.save(SysUserRole.builder()
                .userId(nUser.getId())
                .roleId(2L)
                .build());


        return AjaxResponse.successMsgData("注册成功!", UserRegisterResp.builder()
                .id(nUser.getId())
                .password(nUser.getPassword())
                .username(nUser.getUsername())
                .build());


    }
}

